﻿#include <calibrateWidget.h>
#include <QMessageBox>
#include <QtCore/QDebug>
#include <app.h>
#include <QTextCodec>

const static QString hexahedronTips[] = {
	"第一步：请将模块按下图提示的方向放置于水平面上(默认方向的右平面朝上)，静止一段时间，直至出现下一步的提示",
	"第二步：请将模块按下图提示的方向放置于水平面上(默认方向的左平面朝上)，静止一段时间，直至出现下一步的提示",
	"第三步：请将模块按下图提示的方向放置于水平面上(默认方向的前平面朝上)，静止一段时间，直至出现下一步的提示",
	"第四步：请将模块按下图提示的方向放置于水平面上(默认方向的后平面朝上)，静止一段时间，直至出现下一步的提示",
	"第五步：请将模块按下图提示的方向放置于水平面上(默认方向的上平面朝上)，静止一段时间，直至出现下一步的提示",
	"第六步：请将模块按下图提示的方向放置于水平面上(默认方向的下平面朝上)，静止一段时间，直至校准结束",
	"校准完成！"
};

const static QString imageName[] = {
	"./Resources/ins_right.jpg",
	"./Resources/ins_left.jpg",
	"./Resources/ins_front.jpg",
	"./Resources/ins_back.jpg",
	"./Resources/ins_top.jpg",
	"./Resources/ins_bottom.jpg"
};

CalibrateWidget::CalibrateWidget(ConnectThread *thread, Config *config) :
	_config(config),
	_caliState(""),
    _connectThread(thread),
    _caliProgress(0) {
	//加上这一句才会自动释放对象
	this->setAttribute(Qt::WA_DeleteOnClose);
	ui.setupUi(this);
	//初始化QtAwesome
	QtAwesome* awesome = new QtAwesome();
	awesome->initFontAwesome();
	QVariantMap options;
	//初始化颜色
	options.insert("color", QColor(0x94ffff));
	options.insert("color-active", QColor(0x94ffff));
	//按键添加图标
	ui.getGyroBiasBtn->setIcon(awesome->icon(fa::info, options));
	ui.getAccelBiasBtn->setIcon(awesome->icon(fa::info, options));
	ui.gyroPlaneCaliBtn->setIcon(awesome->icon(fa::minus, options));
	ui.accelHexahedralCaliBtn->setIcon(awesome->icon(fa::cube, options));
	ui.cancelCaliButton->setIcon(awesome->icon(fa::times, options));
	//添加label图标
	QVariantMap optionsLable;
	optionsLable.insert("color", QColor(0x5597a9));
	optionsLable.insert("color-active", QColor(0x5597a9));
	ui.warningIconLabel->setPixmap(awesome->icon(fa::warning, optionsLable).pixmap(ui.warningIconLabel->size()));

	//全部控件失能，等待设备连接
	selectedTips(0);
	setPortControlVisible(false);
	setAllControlEnable(false);

	this->startTimer(50);

	createJsonControlMapping();
}

void CalibrateWidget::createJsonControlMapping() {
	//偏移设置页
	_config->setJsonDirControl("/calibrate/gyroBias/biasX", ui.xGyroBiasDisplay, JsonDirContent::passiveResponse);
	_config->setJsonDirControl("/calibrate/gyroBias/biasY", ui.yGyroBiasDisplay, JsonDirContent::passiveResponse);
	_config->setJsonDirControl("/calibrate/gyroBias/biasZ", ui.zGyroBiasDisplay, JsonDirContent::passiveResponse);

	_config->setJsonDirControl("/calibrate/accelBias/biasX", ui.xAccelBiasDisplay, JsonDirContent::passiveResponse);
	_config->setJsonDirControl("/calibrate/accelBias/biasY", ui.yAccelBiasDisplay, JsonDirContent::passiveResponse);
	_config->setJsonDirControl("/calibrate/accelBias/biasZ", ui.zAccelBiasDisplay, JsonDirContent::passiveResponse);

	//对应叶下增加相应槽
	_config->addJsonDirSlot("/calibrate/set/gyroAllan", this, SLOT(gyroAllanProcessDecode(JsonDirContent)));
	_config->addJsonDirSlot("/calibrate/set/accelHexahedron", this, SLOT(accelHexahedronProcessDecode(JsonDirContent)));
}

//析构函数
CalibrateWidget::~CalibrateWidget() {

}

void CalibrateWidget::gyroAllanProcessDecode(JsonDirContent content) {
	QString *str = (QString *)content.getValue();
	QRegExp stepExp("step(\\d+)");
	QRegExp overExp("over");
	if (str->indexOf(stepExp) >= 0) {
		uint32_t number = stepExp.cap(1).toUInt();
		ui.caliProgressBar->setValue(number);
		ui.caliTextLabel->setText(tr("校准进行中。。。"));
		emit operationRecord(fa::hourglasshalf, QString("校准进度：%1%").arg(number));
	}
	else if (str->indexOf(overExp) >= 0) {
		ui.caliTextLabel->setText(tr("校准完成！"));
		emit operationRecord(fa::check, tr("校准成功"));
		if (QMessageBox::Ok == QMessageBox::information(this, tr("提示"), tr("校准完成！"))) {
			ui.caliProgressBar->setValue(0);
			_caliState = "";
			setAllControlEnable(true);
			setPortControlVisible(false);
		}
	}
}

void CalibrateWidget::updateHexahedronPicture(uint32_t number) {
	QString _imageName = imageName[number];
	QSize labelSize = ui.HexahedralPictureLabel->size();
	QImage image = QImage(_imageName).scaled(labelSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
	QPixmap fitpixmap = QPixmap::fromImage(image);
	ui.HexahedralPictureLabel->setPixmap(fitpixmap);
}

void CalibrateWidget::accelHexahedronProcessDecode(JsonDirContent content) {
	QString *str = (QString *)content.getValue();
	QRegExp stepExp("step(\\d+)");
	QRegExp overExp("over");
	if (str->indexOf(stepExp) >= 0) {
		uint32_t number = stepExp.cap(1).toUInt();
		ui.caliProgressBar->setValue(number - 1);
		//最多六个步骤
		number = qMin<uint32_t>(number, 6);
		ui.HexahedralTipsBrowser->setText(hexahedronTips[number - 1]);
		//提示图片刷新
		updateHexahedronPicture(number - 1);
		ui.caliTextLabel->setText(tr("校准进行中。。。"));
		emit operationRecord(fa::hourglasshalf, QString("校准进度：当前第%1步").arg(number));
	}
	else if (str->indexOf(overExp) >= 0) {
		ui.caliTextLabel->setText(tr("校准完成！"));
		emit operationRecord(fa::check, tr("校准成功"));
		ui.caliProgressBar->setValue(6);
		ui.HexahedralTipsBrowser->setText(hexahedronTips[6]);
		if (QMessageBox::Ok == QMessageBox::information(this, tr("提示"), tr("校准完成！"))) {
			ui.caliProgressBar->setValue(0);
			ui.HexahedralTipsBrowser->clear();
			ui.HexahedralPictureLabel->clear();
			_caliState = "";
			setAllControlEnable(true);
			setPortControlVisible(false);
		}
	}
}

//部分控件可见函数
void CalibrateWidget::setPortControlVisible(bool visible) {
	ui.cancelCaliButton->setVisible(visible);
	ui.caliProgressBar->setVisible(visible);
}

//总控件使能函数
void CalibrateWidget::setAllControlEnable(bool enabled) {
	ui.buttonGroup->setEnabled(enabled);
	ui.getGyroBiasBtn->setEnabled(enabled);
	ui.getAccelBiasBtn->setEnabled(enabled);
	ui.gyroPlaneCaliBtn->setEnabled(enabled);
	ui.accelHexahedralCaliBtn->setEnabled(enabled);

	if (enabled) {
		//获取加速度偏移值
		_config->getJsonDirValue("/calibrate/accelBias/");
		//获取角速度偏移值
		_config->getJsonDirValue("/calibrate/gyroBias/");
	}
}

void CalibrateWidget::timerEvent(QTimerEvent *event) {
	Q_UNUSED(event)

}

//校准子页面切换slot
void CalibrateWidget::selectedTips(int selected) {
	switch (selected) {
	case 0: {
		ui.warningBrowser->clear();
        //添加警告
        ui.warningBrowser->append(tr("加速度校准事项："));
        ui.warningBrowser->append(tr("    1、模块正常工作且非校准的状态下，放置在水平面上开始校准；"));
        ui.warningBrowser->append(tr("    2、按照步骤对模块进行六面校准；"));
        ui.warningBrowser->append(tr("    3、每面校准时需要保持静态稳定至少2秒；"));

		if (_connectThread->isRunning()) {
			//获取加速度偏移值
			_config->getJsonDirValue("/calibrate/accelBias/");
		}
		break;
	}
	case 1: {
		ui.warningBrowser->clear();
		//添加警告
        ui.warningBrowser->append(tr("角速度校准事项："));
        ui.warningBrowser->append(tr("    1、模块正常工作且非校准的状态下，放置在水平面上开始校准；"));
        ui.warningBrowser->append(tr("    2、水平面校准时间30s，校准期间请勿触碰、移动或将模块断电；"));
        ui.warningBrowser->append(tr("    3、若触碰模块将自动重新从头校准；"));

		if (_connectThread->isRunning()) {
			//获取角速度偏移值
			_config->getJsonDirValue("/calibrate/gyroBias/");
		}
		break;
	}
	case 2: {
		ui.warningBrowser->clear();
		//添加警告
        ui.warningBrowser->append(tr("磁力校准事项："));
        ui.warningBrowser->append(tr("    椭球校准暂未开放；"));
		break;
	}
	}
}

//普通按键slot
void CalibrateWidget::calibrationDirective() {
	QPushButton *btn = (QPushButton *)sender();
	//必须打开串口
	if (_connectThread->isRunning()) {
		if (btn->objectName() == ui.getGyroBiasBtn->objectName()) {
			//获取角速度偏移值
			_config->getJsonDirValue("/calibrate/gyroBias/");
			emit operationRecord(fa::info, tr("获取角速度偏移值"));
		}
		else if (btn->objectName() == ui.getAccelBiasBtn->objectName()) {
			//获取加速度偏移值
			_config->getJsonDirValue("/calibrate/accelBias/");
			emit operationRecord(fa::info, tr("获取加速度偏移值"));
		}
		else if (btn->objectName() == ui.gyroPlaneCaliBtn->objectName()) {
			//角速度平面校准
			QString str = "start";
			_config->sendJsonDirValue("/calibrate/set/gyroAllan", &str);
			_caliState = "gyroAllan";
			setAllControlEnable(false);
			ui.caliProgressBar->setRange(0, 100);
			setPortControlVisible(true);
			emit operationRecord(fa::minus, tr("角速度平面校准"));
		}
		else if (btn->objectName() == ui.accelHexahedralCaliBtn->objectName()) {
			//加速度六面校准
			QString str = "start";
			_config->sendJsonDirValue("/calibrate/set/accelHexahedron", &str);
			_caliState = "accelHexahedron";
			setAllControlEnable(false);
			ui.caliProgressBar->setRange(0, 6);
			setPortControlVisible(true);
			ui.HexahedralTipsBrowser->setText(hexahedronTips[0]);
			updateHexahedronPicture(0);
			ui.caliTextLabel->setText(tr("校准进行中。。。"));
			emit operationRecord(fa::cube, tr("加速度六面校准"));
		}
		else if (btn->objectName() == ui.cancelCaliButton->objectName()) {
			//取消校准
			QString str = "stop";
			_config->sendJsonDirValue("/calibrate/set/" + _caliState, &str);
			_caliState = "";
			ui.HexahedralTipsBrowser->clear();
			ui.HexahedralPictureLabel->clear();
			setAllControlEnable(true);
			setPortControlVisible(false);
			ui.caliTextLabel->setText(tr("校准已取消！"));
			emit operationRecord(fa::times, tr("校准已取消"));
		}
	}
}

